// 引入生成 IM userSig 的文件——来自于 debug 文件夹
import {
	genTestUserSig
} from '@/debug/GenerateTestUserSig.js';
import vuex from '@/store/index.js'

// 在项目脚本里引入模块，并初始化
import TIM from 'tim-wx-sdk'; //  小程序环境使用
let options = {
	SDKAppID: 1400622577 // 接入时需要将 0 替换为您的云通信应用的 SDKAppID
};
let tim = TIM.create(options); // SDK 实例通常用 tim 表示


// utils主要用于封装公共方法
const install = (Vue, vm) => {
	vm.$u.utils = {}
	// 封装判断用户是否登录的方法，返回 true 则已登录，否则则执行登录逻辑
	vm.$u.utils.login = async () => {
		// 先尝试从本地存储中匹配用户登录后保存的 token 
		const lifeData = uni.getStorageSync('lifeData')
		const openId = lifeData.vuex_token
		if (openId) return true // 已经读取到了则无需再登录，则此方法直接返回 true
		let params = {}		// 登录接口所需参数对象
		// 未登录则执行以下登录的逻辑
		// 1.调用 uni.getUserProfile() 询问用户是否同意授权登录
		try {
			const res = await uni.getUserProfile({
				desc: '用户登录',
				lang: 'zh_CN'
			})
			// console.log(res); // res[1].userInfo 即可获取到用户的基本信息：头像、名称等
			params.nick_name = res[1].userInfo.nickName
			params.gender = res[1].userInfo.gender === 0 ? 1 : 0;	// 0 女  1 男
			params.avatar_url = res[1].userInfo.avatarUrl
			vm.$u.vuex('vuex_user', res[1].userInfo) // 将用户基本信息保存到 vuex 中
		} catch (e) {
			console.log(e);
			// 用户取消授权的场景
			uni.showToast({
				title: '已取消授权',
				duration: 2000,
				icon: 'none'
			})
			return false
		}
		// console.log(JSON.stringify(res.userInfo)); // res 中就包含了 code 字段值
		// 2.调用 uni.login() 获取用户 code
		const res2 = await uni.login({
			provider: 'weixin', // 登录服务提供商,这里是微信
		})
		const code = res2[1].code // 获取到用户的 code
		params.code = res2[1].code
		// console.log(params);
		// 在当前用户登陆前尝试读取存储在vuex中的推荐人信息(如果是点击别人分享的链接进入的就会有保存)
		params.tj_id = vm.vuex_shareData.tj_id || ''
		params.tj_type = vm.vuex_shareData.tj_type || ''
		// 3.调用登录 API 接口进行登录
		const res3 = await vm.$u.api.login(params)
		console.log('res3', res3);
		vm.$u.vuex('vuex_id', res3.id)
		vm.$u.vuex('vuex_token', res3.token) // 将 openId 保存到 vuex 中
		
		// 3.登陆 IM 即时通讯
		const isImLogin = await vm.$u.utils.imLogin()
		if(!isImLogin) return false
		
		return true
	}

	// 如果传入的 手机号 符合定义好的正则 则此方法返回 true 否则 返回 false
	vm.$u.utils.isPhone = (phone) => {
		// 校验手机号的正则
		let reg = /^1[3|4|5|7|8][0-9]{9}$/;
		if (reg.test(phone)) {
			return true
		}
		return false
	}

	// 格式化时间函数，接收一个长度为 10 位 或者 13 位 的时间戳
	vm.$u.utils.formatDate = (time) => {
		// 如果时间戳是 10位 的就 * 1000 转换为 毫秒
		const _time = time.toString().length > 10 ? time : time * 1000
		// console.log( (new Date()).getDate() );		// 得到今天的 号 数
		// 这里传入的时间戳是 10 位的，表示为秒数，所以要乘以 1000 转换为毫秒
		var date = new Date(_time);
		var Y = date.getFullYear();
		var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1);
		var D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate());
		var h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours());
		var m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes());
		var s = (date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds());

		let strDate = ''

		// 判断一下消息是今天的还是昨天的
		if ((new Date()).getDate() == parseInt(D)) {
			strDate = h + ':' + m // 如果是今天的消息则只显示时间，不显示日期
		} else if ((new Date()).getDate() - parseInt(D) >= 1 && (new Date()).getDate() - parseInt(D) < 2) {
			strDate = '昨天 ' + h + ':' + m
		} else if ((new Date()).getFullYear() - Y > 0) { // 如果不是同一年的消息则展示年份
			strDate = `${Y}年${M}月${D}日 ${h}:${m}` // X年X月X日 00:00 的格式
		} else {
			strDate = `${M}月${D}日 ${h}:${m}` // X月X日 00:00 的格式
		}

		return strDate;
	}

	vm.$u.utils.imLogin = async () => {
		const res = await vm.$u.api.getIMData()		// 获取 IM 登陆信息
		const data = vm.$u.utils.decode(res)		// 解码
		// console.log('IM--', data);
		vm.$u.vuex('vuex_account', data.account)		// 把 IM 登陆信息中的 account 保存到 vuex 中
		vm.$u.vuex('vuex_SDKAppID', data.app_id)
		// console.log('im data', data);
		// 页面加载就登陆 IM 即时通讯
		const userID = data.account
		const userSig = genTestUserSig(userID).userSig
		const promise = await tim.login({
			userID: userID,
			userSig: userSig
		});
		if (promise.code) return false
		// console.log('IM登陆成功', promise);
		// 设置 SDK 日志输出级别，详细分级请参见 setLogLevel 接口的说明
		// tim.setLogLevel(0); // 普通级别，日志量较多，接入时建议使用
		tim.setLogLevel(1); // release级别，SDK 输出关键信息，生产环境时建议使用

		return true
	}
	
	// 解密数据的全局方法
	vm.$u.utils.decode = (string) => {
		let key = '!@*_R#_J';
		string = vm.$u.utils.base64_decode(string);
		let len = key.length;
		let code = '';
		for (let i = 0; i < string.length; i++) {
			let k = i % len;
			code += String.fromCharCode(string.charCodeAt(i) ^ key.charCodeAt(k));
		}
		code = JSON.parse(vm.$u.utils.base64_decode(code));
		return code;
	}
	// base64解密函数
	vm.$u.utils.base64_decode = (data) => {
		var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
		var o1, o2, o3, h1, h2, h3, h4, bits, i = 0,
			ac = 0,
			dec = "",
			tmp_arr = [];
		if (!data) {
			return data;
		}
		data += '';
		do { // unpack four hexets into three octets using index points in b64
			h1 = b64.indexOf(data.charAt(i++));
			h2 = b64.indexOf(data.charAt(i++));
			h3 = b64.indexOf(data.charAt(i++));
			h4 = b64.indexOf(data.charAt(i++));
			bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
			o1 = bits >> 16 & 0xff;
			o2 = bits >> 8 & 0xff;
			o3 = bits & 0xff;
			if (h3 == 64) {
				tmp_arr[ac++] = String.fromCharCode(o1);
			} else if (h4 == 64) {
				tmp_arr[ac++] = String.fromCharCode(o1, o2);
			} else {
				tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);
			}
		} while (i < data.length);
		dec = tmp_arr.join('');
		return dec;
	}
	
}
export default {
	install
}
